package com.onion.utils.template.freemarker;

import freemarker.cache.*;
import freemarker.template.*;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FreemarkerUtils {

    private Configuration cfg;

    public FreemarkerUtils(){
        this(Configuration.VERSION_2_3_30);
    }

    public FreemarkerUtils(Version version){
        Version curVersion = (version != null ? version : Configuration.VERSION_2_3_30);
        this.cfg = new Configuration(Configuration.VERSION_2_3_30);
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
    }

    public FreemarkerUtils buildTemplatePathOnClassPath(String packagePath){
        ClassTemplateLoader classTemplateLoader = new ClassTemplateLoader(FreemarkerUtils.class, packagePath);
        TemplateLoader[] templateLoaders = new TemplateLoader[]{classTemplateLoader, new StringTemplateLoader()};
        MultiTemplateLoader multiTemplateLoader = new MultiTemplateLoader(templateLoaders);
        cfg.setTemplateLoader(multiTemplateLoader);
        //cfg.setClassForTemplateLoading(FreemarkerUtils.class, packagePath);
        return this;
    }

    public FreemarkerUtils buildTemplatePathOnFilePath(String filePath){
        try {
            TemplateLoader[] templateLoaders = new TemplateLoader[]{new FileTemplateLoader(new File(filePath)),
                                                                    new StringTemplateLoader()};
            MultiTemplateLoader multiTemplateLoader = new MultiTemplateLoader(templateLoaders);
            cfg.setTemplateLoader(multiTemplateLoader);
            return this;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String genContent(String templateFile, Map<String, Object> params){
        Template template;
        try{
            template = cfg.getTemplate(templateFile, "UTF-8");
        }catch (IOException exp) {
            throw new RuntimeException(exp);
        }
        return this.doGetContent(template, params);
    }

    public String genContent(String templateKey, String templateString, Map<String, Object> params){
        Template template = null;
        try{
            template = cfg.getTemplate(templateKey, "UTF-8");
        }catch (IOException exp) {
            if(template == null){
                try {
                    template = new Template(templateKey, templateString, cfg);
                } catch (IOException e) {
                    throw new RuntimeException(exp);
                }
            }
        }
        return this.doGetContent(template, params);
    }

    private String doGetContent(Template template, Map<String, Object> params){
        StringWriter stringWriter = new StringWriter();
        BufferedWriter bWriter = new BufferedWriter(stringWriter);
        StringReader reader = null;
        try{
            template.process(params, bWriter);
            reader = new StringReader(stringWriter.toString());
        }catch (IOException e1){
            throw new RuntimeException(e1);
        }catch (TemplateException e2){
            throw new RuntimeException(e2);
        }finally {
            stringWriter.flush();
            try {
                stringWriter.close();
            }catch (IOException e){
                throw new RuntimeException(e);
            }
            try {
                bWriter.flush();
            }catch (IOException e){
                throw new RuntimeException(e);
            }
            try {
                bWriter.close();
            }catch (IOException e){
                throw new RuntimeException(e);
            }
        }

        BufferedReader bReader = new BufferedReader(reader);
        StringBuilder strb = new StringBuilder();
        String line;
        try{
            while ((line = bReader.readLine()) != null) {
                strb.append(line);
                strb.append("\r\n");
            }
            return strb.toString();
        }catch (IOException e){
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args){
        FreemarkerUtils freemarkerUtils = new FreemarkerUtils().buildTemplatePathOnClassPath("/template/ftl");
        Map<String, Object> dataMap = new HashMap<>();
        List<Map<String,Object>> dataList = new ArrayList<>();
        Map<String, Object> data1 = new HashMap<>();
        data1.put("id", 1);
        data1.put("supplier", "s1");
        data1.put("smsType", "通知");
        data1.put("source", "crm");
        data1.put("account", "account1");
        data1.put("status", 0);
        dataList.add(data1);
        Map<String, Object> data2 = new HashMap<>();
        data2.put("id", 2);
        data2.put("supplier", "s2");
        data2.put("smsType", "通知");
        data2.put("source", "css");
        data2.put("account", "account2");
        data2.put("status", 1);
        dataList.add(data2);
        Map<String, Object> data3 = new HashMap<>();
        data3.put("id", 3);
        data3.put("supplier", "s3");
        data3.put("smsType", "通知");
        data3.put("source", "css");
        data3.put("account", "account3");
        data3.put("status", 3);
        dataList.add(data3);
        dataMap.put("dataList", dataList);
        String result = freemarkerUtils.genContent("test.ftl", dataMap);
        System.out.println(result);
    }

}